package top.csmcool.musicapi.resource;



import cn.hutool.json.JSONObject;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import top.csmcool.musicapi.client.KugouClient;
import top.csmcool.musicapi.config.SystemProperties;
import top.csmcool.musicapi.domain.UserPlatformBindInfo;
import top.csmcool.musicapi.domain.Users;
import top.csmcool.musicapi.enums.PlatformEnum;
import top.csmcool.musicapi.model.api.kugou.*;
import top.csmcool.musicapi.model.api.navidrome.LyricLine;
import top.csmcool.musicapi.model.api.navidrome.SongCollection;
import top.csmcool.musicapi.model.api.qq.Singer;
import top.csmcool.musicapi.model.playlist.*;
import top.csmcool.musicapi.util.TreadLocalUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author shizhe
 * @Date 2025/02/08
 */

@Component("kugou")
@RequiredArgsConstructor
public class KugouResource implements MusicResource{

    private final SystemProperties systemProperties;
    private final KugouClient kugouClient;

    @Override
    public List<PlayListMusicInfo> getTracks(TracksRequest requestRequest, Users users, UserPlatformBindInfo one) {
        List<PlayListMusicInfo> result = new LinkedList<>();
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.KUGOU.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("id", requestRequest.getId());
        parameter.set("page", requestRequest.getPage() + 1);
        parameter.set("size", requestRequest.getSize());
        List<Song> songs = kugouClient.playlistTrackAll(parameter);
        for (Song song : songs) {
            PlayListMusicInfo playListMusicInfo = new PlayListMusicInfo();
            playListMusicInfo.setId(song.getHash());
            playListMusicInfo.setName(song.getName());
            String artists = song.getSingerinfo().stream().map(SingerInfo::getName).collect(Collectors.joining("/"));
            playListMusicInfo.setSinger(artists);
            if (song.getAlbuminfo() != null) {
                playListMusicInfo.setAlbum(song.getAlbuminfo().getName());
            }
            playListMusicInfo.setImage(song.getCover());
            playListMusicInfo.setDuration((long) (song.getTimelen() / 1000));
            playListMusicInfo.setUrl("");
            playListMusicInfo.setPlatform(PlatformEnum.KUGOU.getCode());
            playListMusicInfo.setPlatformName(PlatformEnum.KUGOU.getName());
            result.add(playListMusicInfo);
        }

        return result;
    }

    @Override
    public List<LyricInfo> getLyric(LyricRequest body, Users users, UserPlatformBindInfo one) {
        List<LyricInfo> result = new LinkedList<>();
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.KUGOU.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("hash", body.getId());
        SearchLyric searchLyric = kugouClient.searchLyric(parameter);

        if (searchLyric.getCandidates() == null
                || searchLyric.getCandidates().isEmpty()) {
            return result;
        }

        Candidate candidate = searchLyric.getCandidates().get(0);

        JSONObject parameter1 = new JSONObject();
        parameter1.set("id", candidate.getId());
        parameter1.set("accesskey", candidate.getAccesskey());
        parameter1.set("decode", true);
        Lyric lyric = kugouClient.lyric(parameter1);

        String decodeContent = lyric.getDecodeContent();
        if(!StringUtils.hasText(decodeContent)) {
            return result;
        }
        result = parseLyric(decodeContent);
        return result;
    }

    @Override
    public List<SongCollection> getPlayList(PlayListRequest body, Users users, UserPlatformBindInfo one) {

        List<SongCollection> result = new LinkedList<>();
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.KUGOU.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("page", body.getPage() + 1);
        parameter.set("pagesize", body.getSize());
        UserPlayList userPlayList = kugouClient.userPlaylist(parameter);

        List<Info> info = userPlayList.getInfo();
        if(info == null || info.isEmpty()) {
            return result;
        }

        for (Info musicDirectory : info) {
            SongCollection songCollection = getSongCollection(musicDirectory);
            result.add(songCollection);
        }

        return result;
    }

    @Override
    public List<SongCollection> getPublicPlayList(PlayListRequest body, Users users, UserPlatformBindInfo one) {
        List<SongCollection> result = new LinkedList<>();
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.KUGOU.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("category_id", 0);
        MusicCollectionResponse musicCollectionResponse = kugouClient.topPlaylist(parameter);

        List<MusicCollectionItem> specialList = musicCollectionResponse.getSpecial_list();
        if(specialList == null || specialList.isEmpty()) {
            return result;
        }

        for (MusicCollectionItem musicDirectory : specialList) {
            SongCollection songCollection = getSongCollection(musicDirectory);
            result.add(songCollection);
        }

        return result;
    }

    @Override
    public List<PlayListMusicInfo> search(SearchRequest body, Users users, UserPlatformBindInfo one) {

        List<PlayListMusicInfo> result = new LinkedList<>();
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.KUGOU.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("keywords", body.getName());
        parameter.set("page", body.getPage() + 1);
        parameter.set("pagesize", body.getSize());
        SongSearch search = kugouClient.search(parameter);
        List<SongSearchItem> lists = search.getLists();
        if(lists == null || lists.isEmpty()) {
            return result;
        }

        for (SongSearchItem song : lists) {
            PlayListMusicInfo playListMusicInfo = new PlayListMusicInfo();
            playListMusicInfo.setId(song.getFileHash());
            playListMusicInfo.setName(song.getSongName());
            playListMusicInfo.setSinger(song.getSingerName());
            playListMusicInfo.setAlbum(song.getAlbumName());
            playListMusicInfo.setImage(song.getImage());
            playListMusicInfo.setDuration((long) (song.getDuration()));
            playListMusicInfo.setUrl("");
            playListMusicInfo.setPlatform(PlatformEnum.KUGOU.getCode());
            result.add(playListMusicInfo);
        }

        return result;
    }

    @Override
    public SongInfo getSongUrl(SongUrlRequest body, Users users, UserPlatformBindInfo one) {
        SongInfo songInfo = new SongInfo();
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.KUGOU.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);
        JSONObject parameter = new JSONObject();
        parameter.set("hash", body.getId());
        parameter.set("free_part", true);
        MusicInfo musicInfo = kugouClient.songUrl(parameter);
        List<String> url = musicInfo.getUrl();
        songInfo.setSongUrl(url.get(0));
        return songInfo;
    }

    @Override
    public List<LyricInfo> parseLyric(String lrc) {
        List<LyricLine> lyricLines = new ArrayList<>();
        String[] lines = lrc.split("\n");
        Pattern tagPattern = Pattern.compile("<[^>]+>"); // 匹配 <...> 标签
        List<LyricInfo> lyricInfos = new LinkedList<>();
        for (String line : lines) {
            // 提取时间戳和歌词内容
            line = line.replace("\r", "");
            if (line.matches("\\[\\d+,\\d+].*")) { // 匹配时间戳行
                int start = extractStartTime(line); // 提取开始时间
                String content = extractLyricContent(line); // 提取歌词内容
                // 移除 <...> 标签
                Matcher tagMatcher = tagPattern.matcher(content);
                content = tagMatcher.replaceAll("").trim();
                lyricLines.add(new LyricLine(start, content));
            }
        }
        for (LyricLine lyricLine : lyricLines) {
            LyricInfo lyricInfo = new LyricInfo();

            lyricInfo.setText(lyricLine.getValue());
            lyricInfo.setTime(lyricLine.getStart());

            lyricInfos.add(lyricInfo);
        }
        return lyricInfos;
    }

    // 提取开始时间
    private static int extractStartTime(String line) {
        String timePart = line.substring(1, line.indexOf(",")); // 提取时间部分
        return Integer.parseInt(timePart); // 转换为整数
    }

    // 提取歌词内容
    private static String extractLyricContent(String line) {
        int contentStart = line.indexOf(">") + 1; // 找到歌词内容的起始位置
        return line.substring(contentStart).trim(); // 提取并去除前后空格
    }

    private static SongCollection getSongCollection(Info musicDirectory) {
        SongCollection songCollection = new SongCollection();
        songCollection.setId(String.valueOf(musicDirectory.getGlobal_collection_id()));
        songCollection.setCoverImgUrl(musicDirectory.getPic().replace("{size}", "300"));
        songCollection.setName(musicDirectory.getName());
        songCollection.setSongCount(musicDirectory.getM_count());
        songCollection.setOwnerName(musicDirectory.getList_create_username());
        songCollection.setOwnerId(String.valueOf(musicDirectory.getList_create_userid()));
        songCollection.setCreatedAt(String.valueOf(musicDirectory.getCreate_time()));
        songCollection.setUpdatedAt(String.valueOf(musicDirectory.getUpdate_time()));
        return songCollection;
    }

    private static SongCollection getSongCollection(MusicCollectionItem musicDirectory) {
        SongCollection songCollection = new SongCollection();
        songCollection.setId(String.valueOf(musicDirectory.getGlobal_collection_id()));
        songCollection.setCoverImgUrl(musicDirectory.getImgurl().replace("{size}", "300"));
        songCollection.setName(musicDirectory.getSpecialname());
        songCollection.setSongCount(musicDirectory.getCollectcount());
        songCollection.setOwnerName(musicDirectory.getNickname());
        songCollection.setOwnerId(String.valueOf(musicDirectory.getSuid()));
        return songCollection;
    }

    @Override
    public JSONObject requestResource(JSONObject jsonObject, Users users, UserPlatformBindInfo one) {
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);
        return kugouClient.requestResource(jsonObject);
    }
}
